package star.cloud.asme.person.ndePersonCertification;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.file.fileInfo.FileInfo;
import star.cloud.asme.base.file.fileInfo.FileInfoMapper;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;
import star.cloud.asme.base.utils.ObjectsUtil;
import star.cloud.asme.system.user.User;
import star.cloud.asme.system.user.UserMapper;

import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
@RequiredArgsConstructor
public class NdePersonCertificationServiceImpl extends IBaseServiceImpl<NdePersonCertificationMapper, NdePersonCertification> implements NdePersonCertificationService {

    private final NdePersonCertificationMapper ndePersonCertificationMapper;
    private final UserMapper userMapper;
    private final FileInfoMapper fileInfoMapper;

    @Override
    public Result<NdePersonCertification> getOneByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<NdePersonCertification> queryWrapper = new LambdaQueryWrapper<>();

        switch (columnName) {
            case "id" -> queryWrapper.eq(NdePersonCertification::getId, columnValue);
            case "username" -> queryWrapper.eq(NdePersonCertification::getUsername, columnValue);
        }

        NdePersonCertification ndePersonCertification = ndePersonCertificationMapper.selectOne(queryWrapper);
        User user = userMapper.selectOneByUsername(ndePersonCertification.getUsername());

        setCreatorAndUpdater(ndePersonCertification);
        ndePersonCertification.setUser(user);
        return Result.ok(ndePersonCertification);
    }

    @Override
    public Result<List<NdePersonCertification>> getListByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<NdePersonCertification> queryWrapper = new LambdaQueryWrapper<>();
        List<NdePersonCertification> asmePersonInfoList = ndePersonCertificationMapper.selectList(queryWrapper);
        return Result.ok(asmePersonInfoList);
    }

    @Override
    public Result<List<NdePersonCertification>> getListByConditions(NdePersonCertification conditions) {
        LambdaQueryWrapper<NdePersonCertification> queryWrapper = new LambdaQueryWrapper<>();
        List<NdePersonCertification> asmePersonInfoList = ndePersonCertificationMapper.selectList(queryWrapper);
        return Result.ok(asmePersonInfoList);
    }

    @Override
    public Result<IPage<NdePersonCertification>> getListByConditionsWithPage(NdePersonCertification conditions) {
        IPage<NdePersonCertification> ipage = new Page<>(conditions.getCurrentPage(), conditions.getPageSize());
        LambdaQueryWrapper<NdePersonCertification> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getUsername()), NdePersonCertification::getUsername, conditions.getUsername());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getMethod()), NdePersonCertification::getMethod, conditions.getMethod());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getLevel()), NdePersonCertification::getLevel, conditions.getLevel());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getDomain()), NdePersonCertification::getDomain, conditions.getDomain());
        queryWrapper.eq(conditions.getIsLatest(), NdePersonCertification::getIsLatest, conditions.getIsLatest());
        queryWrapper.ge(conditions.getIsValid(), NdePersonCertification::getEndDate, LocalDate.now());
        queryWrapper.like(ObjectsUtil.noNullAndEmpty(conditions.getReference()), NdePersonCertification::getReference, "%" + conditions.getReference() + "%");
        queryWrapper.orderByAsc(NdePersonCertification::getUsername);
        queryWrapper.orderByAsc(NdePersonCertification::getDomain);
        queryWrapper.orderByAsc(NdePersonCertification::getMethod);
        queryWrapper.orderByAsc(NdePersonCertification::getStartDate);
        ndePersonCertificationMapper.selectPage(ipage, queryWrapper);
        setCreatorAndUpdater(ipage);
        ipage.getRecords().forEach(personCertification -> {
            FileInfo fileInfo = fileInfoMapper.selectOneByKeyWord(personCertification.getAttachmentUuid());
            if (fileInfo != null) {
                personCertification.setAttachmentUrl(fileInfo.getUrl());
            }
            setIsValid(personCertification);
            personCertification.setInitNdeDate(ndePersonCertificationMapper.getInitNdeDate(personCertification));
            personCertification.setInitMethodDate(ndePersonCertificationMapper.getInitMethodDate(personCertification));
            personCertification.setInitMethodDomainDate(ndePersonCertificationMapper.getInitMethodDomainDate(personCertification));
            personCertification.setInitMethodDomainLevelDate(ndePersonCertificationMapper.getInitMethodDomainLevelDate(personCertification));
        });
        return Result.ok(ipage);
    }


    @Override
    public Result<NdePersonCertification> insertOne(NdePersonCertification entity) {
        if (!entity.getStartDate().isBefore(entity.getEndDate())) {
            return Result.error(entity).msg("有效期至应该在发证日期之后。");
        }
        entity.setAttachmentUuid(UUID.randomUUID().toString());
        User user = userMapper.selectOneByUsername(entity.getUsername());
        entity.setName(user.getName());
        entity.setWorkNo(user.getWorkNo());
        int inserted = ndePersonCertificationMapper.insert(entity);

        if (inserted > 0) {
            setIsLatest(entity);
            setCreatorAndUpdater(entity);
            entity.setUser(user);
            return Result.ok(entity).msg("新增无损检测人员证书成功。");
        } else {
            return Result.error(entity).msg("新增无损检测人员证书失败。");
        }

    }

    @Override
    public Result<NdePersonCertification> updateOne(NdePersonCertification entity) {
        if (!entity.getStartDate().isBefore(entity.getEndDate())) {
            return Result.error(entity).msg("有效期至应该在发证日期之后。");
        }
        User user = userMapper.selectOneByUsername(entity.getUsername());
        setVersion(entity);
        int updateById = ndePersonCertificationMapper.updateById(entity);
        if (updateById > 0) {
            setIsLatest(entity);
            setCreatorAndUpdater(entity);
            entity.setUser(user);
            return Result.ok(entity).msg("修改无损检测人员证书成功。");
        } else {
            return Result.error(entity).msg("修改无损检测人员证书失败。");
        }
    }

    private void setIsLatest(NdePersonCertification ndePersonCertification) {
        //非常重要：以下语句顺序不可颠倒
        ndePersonCertificationMapper.updateIsLatestToFalse(ndePersonCertification);
        ndePersonCertificationMapper.updateIsLatestToTrue(ndePersonCertification);
    }

    private void setIsValid(NdePersonCertification ndePersonCertification) {
        ndePersonCertification.setIsValid(!LocalDate.now().isAfter(ndePersonCertification.getEndDate()));
    }

}
